fix(slack-bot): stop intermediate agent narration leaking into final response#1675
Closed
cisco-erilutz wants to merge 1 commit into
Conversation
…response [GAI] The Slack bot reconstructs the final answer from the AG-UI SSE event stream. Two paths could leak intermediate "Let me…" narration into the message body once the LLM client began emitting inter-step text deltas: - TEXT_MESSAGE_CONTENT that arrived while a tool was active was streamed live via appendStream, so every narration segment was written to the body. - accumulated_text (never reset) was used as a final-answer fallback, so it could surface the entire concatenated transcript at finalization and on the RUN_ERROR recovery path. Now text is never streamed to the body mid-run. Text emitted while a tool is active is treated as discardable narration (it only feeds the typing indicator); text emitted when no tool is active is buffered and cleared on the next tool start, so only the text after the last tool call — the real answer — is rendered. The accumulated_text buffer is removed entirely; finalization and error recovery both use that single buffer. Add a regression test covering narration emitted while a tool is active (the case the previous between-tools test did not exercise). Signed-off-by: Erik Lutz <elutz@splunk.com>
4ba3a7a to
6ef0cdb
Compare
Prebuild Artifacts for
|
| Artifact | Image | Tag | Status | CI |
|---|---|---|---|---|
| caipe-slack-bot | ghcr.io/cnoe-io/prebuild/caipe-slack-bot |
fix-slack-bot-thinking-text-leak-2 |
Published | CI |
Docker pull commands
docker pull ghcr.io/cnoe-io/prebuild/caipe-slack-bot:fix-slack-bot-thinking-text-leak-2These prebuild artifacts will be automatically cleaned up when the PR is closed or merged.
Prebuild Artifacts for
|
| Artifact | Image | Tag | Status | CI |
|---|---|---|---|---|
| caipe-slack-bot | ghcr.io/cnoe-io/prebuild/caipe-slack-bot |
fix-slack-bot-thinking-text-leak-2 |
Published | CI |
Docker pull commands
docker pull ghcr.io/cnoe-io/prebuild/caipe-slack-bot:fix-slack-bot-thinking-text-leak-2These prebuild artifacts will be automatically cleaned up when the PR is closed or merged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stacked on top of #1609 (the Anthropic Bedrock client switch). That switch surfaced a latent bug in the Slack bot's response reconstruction: intermediate agent narration ("Now let me search…", "I notice the pagination is returning the same data…") leaks into the final Slack message body, in front of the real answer.
prebuild/branch so prebuild slack-bot images are published for testing.Root cause
The Slack bot rebuilds the final answer from the AG-UI SSE event stream (
integrations/slack_bot/utils/ai.py), not from theAIMessagedirectly. TheChatBedrockConverse→ChatAnthropicBedrockchange altered which intermediate text reaches the bot asTEXT_MESSAGE_CONTENTdeltas — the Anthropic client emits per-step narration tokens that the converse path did not surface. That exposed two flaws:TEXT_MESSAGE_CONTENTarriving while a tool was active (stream already open in todo/plan mode) was streamed live viaappendStream, so every narration segment was written straight into the message body.accumulated_text(which was never reset during a run) was used as a final-answer fallback, so the entire concatenated transcript could surface at finalization and on theRUN_ERRORrecovery path.Fix
TOOL_CALL_START, so only the text after the last tool call (the real answer) is rendered at finalization.accumulated_textbuffer entirely; finalization and error recovery now use the single answer buffer.Tests
integrations/slack_botsuite passes (179 tests).🤖 Generated with Claude Code